﻿#region Using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using KohvikRax.Resources.Src;
using System.Collections.ObjectModel;
#endregion

namespace KohvikRax
{


    public partial class MainWindow : Window
    {
        private static DataSync _dataSync;

        /************************************ Missing a thread safe wrapper ***************************/
        private static ObservableCollection<CoffeeService.EntityKohvik> _kohvikList = 
            new ObservableCollection<CoffeeService.EntityKohvik>();
        private static ObservableCollection<CoffeeService.EntityUudis> _uudisList = 
            new ObservableCollection<CoffeeService.EntityUudis>();
        /**********************************************************************************************/

        private static bool _IsUpdateAvailableForGenericData = false;
        private static readonly int GLOBAL_UPDATE_INTERVAL_SEC = 59;









        private static ObservableCollection<OpenTime> _selectedOpenTimesList =
            new ObservableCollection<OpenTime>();

        private static ObservableCollection<Comment> _selectedCommentList =
            new ObservableCollection<Comment>();

        private static ObservableCollection<AddressWrapper> _selectedAddressItemList =
            new ObservableCollection<AddressWrapper>();

        private delegate void UpdateSpecificData(EDataTypeUpdate e, int i);

        private static MainWindow mainWindowRef;

        public MainWindow()
        {
            InitializeComponent();
            listBox_kohvik.ItemsSource = _kohvikList;
            listBox_uudis.ItemsSource = _uudisList;
            listBox_kohvikLahtiolek.ItemsSource = _selectedOpenTimesList;
            listBox_kommentaarid.ItemsSource = _selectedCommentList;
            listBox_aadressid.ItemsSource = _selectedAddressItemList;

            listBox_kohvik.SelectionChanged += delegate(object sender, SelectionChangedEventArgs e)
            {
                var selectedK = listBox_kohvik.SelectedValue as CoffeeService.EntityKohvik;
                UpdateKohvikDisplay(selectedK);
            };

            listBox_uudis.SelectionChanged += delegate(object sender, SelectionChangedEventArgs e)
            {
                var uudisPicked = listBox_uudis.SelectedValue as CoffeeService.EntityUudis;
                UpdateUudisDisplay(uudisPicked);
            };

            mainWindowRef = this;
        }



        static MainWindow()
        {

            _dataSync = DataSync.GetInstance();
            _dataSync.UpdateData(EDataTypeUpdate.AllKohvikEntities | EDataTypeUpdate.TopNews);
            var kohvikIterator = _dataSync.KohvikEntityList;
            var uudisIterator = _dataSync.UudisEntityList;

            foreach (var k in kohvikIterator)
            {
                _kohvikList.Add(k);
            }

            foreach (var u in uudisIterator)
            {
                _uudisList.Add(u);
            }
            
            _dataSync.UpdateSettings = EDataTypeUpdate.AllGeneral;
            _dataSync.StartAsyncUpdater(GLOBAL_UPDATE_INTERVAL_SEC, new AsyncCallback
                ((i) =>
                    {
                        var d = Application.Current.Dispatcher;
                        d.BeginInvoke
                            ((Action)(() =>
                                {
                                    _IsUpdateAvailableForGenericData = true;
                                }
                            ));
                    }
                ));
        }

        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
        private static void UpdateGenericData()
        {
            if(_IsUpdateAvailableForGenericData)
            {
                _IsUpdateAvailableForGenericData = false;
                var kIterator = _dataSync.KohvikEntityList;
                var uIterator = _dataSync.UudisEntityList;

                _kohvikList.Clear();
                foreach (var k in kIterator)
                {
                    _kohvikList.Add(k);
                }
                _uudisList.Clear();
                foreach (var u in uIterator)
                {
                    _uudisList.Add(u);
                }
            }
        }

        /**
         * No cache,
         * clicks are history queued,
         * data is displayed after a successful query session
         **/
        private static void UpdateKohvikDisplay(CoffeeService.EntityKohvik kohvik)
        {
            EDataTypeUpdate _displayItemsToUpdate =
            EDataTypeUpdate.CafeOpenTimes | EDataTypeUpdate.CafeCommentCount |
            EDataTypeUpdate.CafeComments;

            UpdateSpecificData u = _dataSync.UpdateData;
            u.BeginInvoke(_displayItemsToUpdate, kohvik.Kohvik_ID, new AsyncCallback(UpadteKohvikDisplayCallback), null);
        }

        private static void UpadteKohvikDisplayCallback( IAsyncResult iar )
        {
            var dispatcher = Application.Current.Dispatcher;
            dispatcher.BeginInvoke((Action)(() =>
            {

                // UpdateGenericData() :: Requires thread safe wrapper around ObservableCollection to be available for use
                if (_selectedOpenTimesList.Count != 0) _selectedOpenTimesList.Clear();

                var selectedTimes = _dataSync.SelectedCafeOpenTimes;

                if (selectedTimes == null || selectedTimes.Count() == 0)
                {
                    _selectedOpenTimesList.Add(new OpenTime()
                    {
                        Day = "Polegi!"
                    });
                }
                else
                {
                    foreach (var singleOpenTime in _dataSync.SelectedCafeOpenTimes)
                    {
                        _selectedOpenTimesList.Add(singleOpenTime);
                    }
                }

                if (_selectedCommentList.Count != 0) _selectedCommentList.Clear();

                var selectedComments = _dataSync.SelectedCafeComments;

                if (selectedComments == null || selectedComments.Count == 0)
                {
                    _selectedCommentList.Add(new Comment()
                    {
                        Header = "Tule meie veebiportaali ja ole esimene kommenteerija ",
                        Body = "Kõikide 'esimeste' kommenteerijate vahel loositakse välja iPad 2 võitja!) "
                    });
                }
                else
                {
                    foreach (var comment in selectedComments)
                    {
                        _selectedCommentList.Add(comment);
                    }
                }

                StringBuilder sb = new StringBuilder(100);
                var selectedKohvik = (from kohvik in _kohvikList
                                      where kohvik.Kohvik_ID == _dataSync.SelectedCafeId
                                      select kohvik).First();

                if (_selectedAddressItemList.Count != 0)
                {
                    _selectedAddressItemList.Clear();
                }

                {
                    sb.Append(selectedKohvik.Tanav);
                    sb.Append(" ");
                    sb.Append(selectedKohvik.Maja);
                    sb.Append(" ");
                    sb.Append(selectedKohvik.Indeks);
                    _selectedAddressItemList.Add(new AddressWrapper() { AddressItem = sb.ToString() });
                    _selectedAddressItemList.Add(new AddressWrapper() { AddressItem = selectedKohvik.LinnVald });
                    _selectedAddressItemList.Add(new AddressWrapper() { AddressItem = selectedKohvik.Maakond });
                    sb.Clear();
                }


                
                sb.Append(selectedKohvik.Nimi);
                sb.Append(" ( ");
                sb.Append(_dataSync.SelectedCafeCommentCount);
                sb.Append(" )");
                mainWindowRef.label_kohvikNimi.Content = sb.ToString();

            }));

        }
        
        /**
         * All data regarding news is held in the same table
         **/
        private static void UpdateUudisDisplay(CoffeeService.EntityUudis uudis)
        {
            var sb = new StringBuilder(300);

            sb.Append
                ((
                from kohvik in _kohvikList
                where kohvik.Kohvik_ID == uudis.Kohvik_ID
                select kohvik).First().Nimi
                );
            sb.Append(" ( ");
            sb.Append(uudis.Aeg.ToString().Remove(9));
            sb.Append(" )");
            mainWindowRef.label_uudised_kohvikNimi.Content = sb.ToString();
            sb.Clear();

            sb.Append(uudis.Pealkiri);
            sb.AppendLine();
            sb.AppendLine();
            sb.AppendLine();
            sb.Append(uudis.Uudis);
            mainWindowRef.textBox_uudised.Text = sb.ToString(); 
        }
    }
}

